package com.magenta.maxoptra.gis.utils;

import java.util.*;

/**
 * @author Sergey Grachev
 */
public final class DatabaseUtils {
    private DatabaseUtils() {
    }

    public static Map<Integer, Object> makeQueryParams(final Object... objects) {
        final Map<Integer, Object> result = new HashMap<Integer, Object>(objects.length);
        int i = 1;
        for (final Object o : objects) {
            result.put(i++, o);
        }
        return result;
    }

    public static String inStatement(final Map<Integer, Object> params, final Collection args) {
        final StringBuilder sb = new StringBuilder("(");
        int i = params.size();
        for (final Object o : args) {
            params.put(++i, o);
            if (sb.length() > 1) {
                sb.append(",");
            }
            sb.append("?");
        }
        sb.append(")");
        return sb.toString();
    }

    public static <P, R> List<R> mapRows(final List rows, final RowMapper<P, R> mapper) {
        final List<R> result = new ArrayList<R>();
        for (final Object row : rows) {
            @SuppressWarnings("unchecked")
            final P cast = (P) row;
            result.add(mapper.map(cast));
        }
        return result;
    }

    public static <P, G, R> Map<G, Set<R>> mapGroupRowsAsSet(final List rows, final RowGroupMapper<P, G, R> mapper) {
        final Map<G, Set<R>> result = new HashMap<G, Set<R>>();
        for (final Object row : rows) {
            @SuppressWarnings("unchecked")
            final P castRow = (P) row;
            final G group = mapper.group(castRow);
            Set<R> list = result.get(group);
            if (list == null) {
                result.put(group, list = new HashSet<R>());
            }
            list.add(mapper.map(castRow));
        }
        return result;
    }

    public static interface RowMapper<P, R> {
        R map(P row);
    }

    public static interface RowGroupMapper<P, G, R> {
        R map(P row);

        G group(P row);
    }
}
